layui.define('jquery', function (exports) {

  //依赖jQuery
  var jQuery = layui.jquery;

  (function(jQuery) {
    var $, Collapser, JSONFormatter, JSONView;
    JSONFormatter = (function() {
      function JSONFormatter(options) {
        if (options == null) {
          options = {};
        }
        this.options = options;
      }

      JSONFormatter.prototype.htmlEncode = function(html) {
        if (html !== null) {
          return html.toString().replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
        } else {
          return '';
        }
      };

      JSONFormatter.prototype.jsString = function(s) {
        s = JSON.stringify(s).slice(1, -1);
        return this.htmlEncode(s);
      };

      JSONFormatter.prototype.decorateWithSpan = function(value, className) {
        return "<span class=\"" + className + "\">" + (this.htmlEncode(value)) + "</span>";
      };

      JSONFormatter.prototype.valueToHTML = function(value, level) {
        var valueType;
        if (level == null) {
          level = 0;
        }
        valueType = Object.prototype.toString.call(value).match(/\s(.+)]/)[1].toLowerCase();
        return this["" + valueType + "ToHTML"].call(this, value, level);
      };

      JSONFormatter.prototype.nullToHTML = function(value) {
        return this.decorateWithSpan('null', 'null');
      };

      JSONFormatter.prototype.numberToHTML = function(value) {
        return this.decorateWithSpan(value, 'num');
      };

      JSONFormatter.prototype.stringToHTML = function(value) {
        var multilineClass, newLinePattern;
        if (/^(http|https|file):\/\/[^\s]+$/i.test(value)) {
          return "<a href=\"" + (this.htmlEncode(value)) + "\"><span class=\"q\">\"</span>" + (this.jsString(value)) + "<span class=\"q\">\"</span></a>";
        } else {
          multilineClass = '';
          value = this.jsString(value);
          if (this.options.nl2br) {
            newLinePattern = /([^>\\r\\n]?)(\\r\\n|\\n\\r|\\r|\\n)/g;
            if (newLinePattern.test(value)) {
              multilineClass = ' multiline';
              value = (value + '').replace(newLinePattern, '$1' + '<br />');
            }
          }
          return "<span class=\"string" + multilineClass + "\">\"" + value + "\"</span>";
        }
      };

      JSONFormatter.prototype.booleanToHTML = function(value) {
        return this.decorateWithSpan(value, 'bool');
      };

      JSONFormatter.prototype.arrayToHTML = function(array, level) {
        var collapsible, hasContents, index, numProps, output, value, _i, _len;
        if (level == null) {
          level = 0;
        }
        hasContents = false;
        output = '';
        numProps = array.length;
        for (index = _i = 0, _len = array.length; _i < _len; index = ++_i) {
          value = array[index];
          hasContents = true;
          output += '<li>' + this.valueToHTML(value, level + 1);
          if (numProps > 1) {
            output += ',';
          }
          output += '</li>';
          numProps--;
        }
        if (hasContents) {
          collapsible = level === 0 ? '' : ' collapsible';
          return "[<ul class=\"array level" + level + collapsible + "\">" + output + "</ul>]";
        } else {
          return '[ ]';
        }
      };

      JSONFormatter.prototype.objectToHTML = function(object, level) {
        var collapsible, hasContents, numProps, output, prop, value;
        if (level == null) {
          level = 0;
        }
        hasContents = false;
        output = '';
        numProps = 0;
        for (prop in object) {
          numProps++;
        }
        for (prop in object) {
          value = object[prop];
          hasContents = true;
          output += "<li><span class=\"prop\"><span class=\"q\">\"</span>" + (this.jsString(prop)) + "<span class=\"q\">\"</span></span>: " + (this.valueToHTML(value, level + 1));
          if (numProps > 1) {
            output += ',';
          }
          output += '</li>';
          numProps--;
        }
        if (hasContents) {
          collapsible = level === 0 ? '' : ' collapsible';
          return "{<ul class=\"obj level" + level + collapsible + "\">" + output + "</ul>}";
        } else {
          return '{ }';
        }
      };

      JSONFormatter.prototype.jsonToHTML = function(json) {
        return "<div class=\"modules\">" + (this.valueToHTML(json)) + "</div>";
      };

      return JSONFormatter;

    })();
    (typeof module !== "undefined" && module !== null) && (module.exports = JSONFormatter);
    Collapser = {
      bindEvent: function(item, collapsed) {
        var collapser;
        collapser = document.createElement('div');
        collapser.className = 'collapser';
        collapser.innerHTML = collapsed ? '+' : '-';
        collapser.addEventListener('click', (function(_this) {
          return function(event) {
            return _this.toggle(event.target);
          };
        })(this));
        item.insertBefore(collapser, item.firstChild);
        if (collapsed) {
          return this.collapse(collapser);
        }
      },
      expand: function(collapser) {
        var ellipsis, target;
        target = this.collapseTarget(collapser);
        ellipsis = target.parentNode.getElementsByClassName('ellipsis')[0];
        target.parentNode.removeChild(ellipsis);
        target.style.display = '';
        return collapser.innerHTML = '-';
      },
      collapse: function(collapser) {
        var ellipsis, target;
        target = this.collapseTarget(collapser);
        target.style.display = 'none';
        ellipsis = document.createElement('span');
        ellipsis.className = 'ellipsis';
        ellipsis.innerHTML = ' &hellip; ';
        target.parentNode.insertBefore(ellipsis, target);
        return collapser.innerHTML = '+';
      },
      toggle: function(collapser) {
        var target;
        target = this.collapseTarget(collapser);
        if (target.style.display === 'none') {
          return this.expand(collapser);
        } else {
          return this.collapse(collapser);
        }
      },
      collapseTarget: function(collapser) {
        var target, targets;
        targets = collapser.parentNode.getElementsByClassName('collapsible');
        if (!targets.length) {
          return;
        }
        return target = targets[0];
      }
    };
    $ = jQuery;
    JSONView = {
      collapse: function(el) {
        if (el.innerHTML === '-') {
          return Collapser.collapse(el);
        }
      },
      expand: function(el) {
        if (el.innerHTML === '+') {
          return Collapser.expand(el);
        }
      },
      toggle: function(el) {
        return Collapser.toggle(el);
      }
    };
    return $.fn.JSONView = function() {
      var args, defaultOptions, formatter, json, method, options, outputDoc;
      args = arguments;
      if (JSONView[args[0]] != null) {
        method = args[0];
        return this.each(function() {
          var $this, level;
          $this = $(this);
          if (args[1] != null) {
            level = args[1];
            return $this.find(".modules .collapsible.level" + level).siblings('.collapser').each(function() {
              return JSONView[method](this);
            });
          } else {
            return $this.find('.modules > ul > li > .collapsible').siblings('.collapser').each(function() {
              return JSONView[method](this);
            });
          }
        });
      } else {
        json = args[0];
        options = args[1] || {};
        defaultOptions = {
          collapsed: false,
          nl2br: false
        };
        options = $.extend(defaultOptions, options);
        formatter = new JSONFormatter({
          nl2br: options.nl2br
        });
        if (Object.prototype.toString.call(json) === '[object String]') {
          json = JSON.parse(json);
        }
        outputDoc = formatter.jsonToHTML(json);
        return this.each(function() {
          var $this, item, items, _i, _len, _results;
          $this = $(this);
          $this.html(outputDoc);
          items = $this[0].getElementsByClassName('collapsible');
          _results = [];
          for (_i = 0, _len = items.length; _i < _len; _i++) {
            item = items[_i];
            if (item.parentNode.nodeName === 'LI') {
              _results.push(Collapser.bindEvent(item.parentNode, options.collapsed));
            } else {
              _results.push(void 0);
            }
          }
          return _results;
        });
      }
    };
  })(jQuery);

  exports('jsonview', null);

});